import matplotlib
matplotlib.use('TkAgg')  # 强制使用 TkAgg 后端，避免兼容性问题

import tkinter as tk
from tkinter import ttk
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

# 设置 Matplotlib 的全局字体为 SimHei（黑体），确保支持中文
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用黑体显示中文
plt.rcParams['axes.unicode_minus'] = False   # 正常显示负号

# 定义攻击力和防御力的范围
attack = np.linspace(200, 1050, 100)  # 攻击力范围
defense = np.linspace(200, 1050, 100)  # 防御力范围
X, Y = np.meshgrid(attack, defense)

# 计算伤害倍率
def calculate_damage(attack, defense):
    # 避免分母为 0 或接近 0 的问题，同时处理无效值
    Z = attack / defense
    Z = np.nan_to_num(Z, nan=0.0, posinf=0.0, neginf=0.0)  # 替换 NaN 和 Inf
    Z = np.clip(Z, 0, 10)  # 限制伤害倍率的范围为 0 到 10（可根据需求调整）
    return Z

# 绘制三维图像
def plot_3d():
    global canvas, ax
    # 清除旧画布
    for widget in canvas_frame.winfo_children():
        widget.destroy()

    # 创建新的图像
    fig = plt.figure(figsize=(8, 6))
    ax = fig.add_subplot(111, projection='3d')
    Z = calculate_damage(X, Y)

    # 绘制三维曲面图
    ax.plot_surface(X, Y, Z, cmap='viridis', alpha=0.8)
    ax.set_title("三维图：攻击力、防御力与伤害倍率的关系", fontsize=12)

    # 坐标轴范围设置部分
    ax.set_xlim(0, X.max())  # 攻击力范围从 0 开始
    ax.set_ylim(0, Y.max())  # 防御力范围从 0 开始
    ax.set_zlim(0, Z.max())  # 伤害倍率范围从 0 开始
    ax.invert_yaxis()  # 反转防御轴方向

    # 设置坐标轴标签
    ax.set_xlabel('攻击力', fontsize=10)
    ax.set_ylabel('防御力', fontsize=10)
    ax.set_zlabel('伤害倍率', fontsize=10)

    # 嵌入到 tkinter 中
    canvas = FigureCanvasTkAgg(fig, master=canvas_frame)
    canvas.get_tk_widget().pack()
    canvas.draw()

# 绘制二维图像
def plot_2d(x_fixed=None, y_fixed=None, z_fixed=None):
    global canvas, ax
    # 清除旧画布
    for widget in canvas_frame.winfo_children():
        widget.destroy()

    # 创建新的图像
    fig = plt.figure(figsize=(8, 6))
    ax = fig.add_subplot(111)  # 切换为二维坐标系

    if z_fixed is not None:
        # 固定 z（伤害倍率）
        defense_values = np.linspace(200, 1050, 100)
        attack_values = z_fixed * defense_values
        ax.plot(attack_values, defense_values, label=f'伤害倍率={z_fixed}')
        ax.set_title(f'二维图：固定伤害倍率={z_fixed} (攻击力 vs 防御力)', fontsize=12)
        ax.set_xlabel('攻击力', fontsize=10)
        ax.set_ylabel('防御力', fontsize=10)
        ax.invert_yaxis()  # 反转防御轴方向
        # 坐标轴范围设置部分
        ax.set_xlim(0, attack_values.max())  # 攻击力范围从 0 开始
        ax.set_ylim(0, defense_values.max())  # 防御力范围从 0 开始

    elif y_fixed is not None:
        # 固定 y（防御力）
        attack_values = np.linspace(200, 1050, 100)
        damage_values = calculate_damage(attack_values, y_fixed)
        ax.plot(attack_values, damage_values, label=f'防御力={y_fixed}')
        ax.set_title(f'二维图：固定防御力={y_fixed} (攻击力 vs 伤害倍率)', fontsize=12)
        ax.set_xlabel('攻击力', fontsize=10)
        ax.set_ylabel('伤害倍率', fontsize=10)
        # 坐标轴范围设置部分
        ax.set_xlim(0, attack_values.max())  # 攻击力范围从 0 开始
        ax.set_ylim(0, damage_values.max())  # 伤害倍率范围从 0 开始

    elif x_fixed is not None:
        # 固定 x（攻击力）
        defense_values = np.linspace(200, 1050, 100)
        damage_values = calculate_damage(x_fixed, defense_values)
        ax.plot(defense_values, damage_values, label=f'攻击力={x_fixed}')
        ax.set_title(f'二维图：固定攻击力={x_fixed} (防御力 vs 伤害倍率)', fontsize=12)
        ax.set_xlabel('防御力', fontsize=10)
        ax.set_ylabel('伤害倍率', fontsize=10)
        ax.invert_xaxis()  # 反转 X 轴方向
        # 坐标轴范围设置部分
        ax.set_xlim(0, defense_values.max())  # 防御力范围从 0 开始
        ax.set_ylim(0, damage_values.max())  # 伤害倍率范围从 0 开始

    # 添加图例
    ax.legend()

    # 嵌入到 tkinter 中
    canvas = FigureCanvasTkAgg(fig, master=canvas_frame)
    canvas.get_tk_widget().pack()
    canvas.draw()

# 提交输入值并切换图像
def on_submit():
    x_value = x_entry.get()
    y_value = y_entry.get()
    z_value = z_entry.get()

    # 确定哪个值固定
    x_fixed = float(x_value) if x_value else None
    y_fixed = float(y_value) if y_value else None
    z_fixed = float(z_value) if z_value else None

    # 如果有输入值，则切换到二维图像
    if x_fixed or y_fixed or z_fixed:
        plot_2d(x_fixed=x_fixed, y_fixed=y_fixed, z_fixed=z_fixed)
    else:
        # 如果没有输入值，显示默认三维图像
        plot_3d()

# 创建 tkinter 窗口
root = tk.Tk()
root.title("伤害倍率函数图像显示")

# 创建输入框和标签
frame = ttk.Frame(root, padding="10")
frame.grid(row=0, column=0, sticky=(tk.W, tk.E))

x_label = ttk.Label(frame, text="固定攻击力（X）:")
x_label.grid(row=0, column=0, sticky=tk.W)
x_entry = ttk.Entry(frame, width=10)
x_entry.grid(row=0, column=1, sticky=(tk.W, tk.E))

y_label = ttk.Label(frame, text="固定防御力（Y）:")
y_label.grid(row=1, column=0, sticky=tk.W)
y_entry = ttk.Entry(frame, width=10)
y_entry.grid(row=1, column=1, sticky=(tk.W, tk.E))

z_label = ttk.Label(frame, text="固定伤害倍率（Z）:")
z_label.grid(row=2, column=0, sticky=tk.W)
z_entry = ttk.Entry(frame, width=10)
z_entry.grid(row=2, column=1, sticky=(tk.W, tk.E))

submit_button = ttk.Button(frame, text="绘图", command=on_submit)
submit_button.grid(row=3, column=0, columnspan=2)

# 创建 matplotlib 图像显示区域
canvas_frame = ttk.Frame(root, padding="10")
canvas_frame.grid(row=1, column=0, sticky=(tk.W, tk.E))

# 初始显示三维图像
plot_3d()

# 启动 tkinter 主循环
root.mainloop()
